import { createLocalVue } from '@vue/test-utils';
import router from '@/router';
import axios from 'axios';
import AccountService from '@/account/account.service';
<%_ if (enableTranslation) { _%>
import TranslationService from '@/locale/translation.service';
<%_ } %>
<%_ if (websocket === 'spring-websocket') { _%>
import TrackerService from '@/admin/tracker/tracker.service';
<%_ } _%>
import * as config from '@/shared/config/config';

const mockedAxios: any = axios;
jest.mock('axios', () => ({
  get: jest.fn(),
  post: jest.fn()
}));
<%_ if (authenticationType === 'session' || authenticationType === 'oauth2') { _%>
const mockedCookie = { get: jest.fn(() => { return 'token'; }) };
<%_ } %>
const localVue = createLocalVue();
<%_ if (enableTranslation) { _%>
let i18n;
<%_ } %>
let store;

describe('Account Service test suite', () => {
  let accountService: AccountService;

  beforeEach(() => {
    mockedAxios.get.mockReset();
    store = config.initVueXStore(localVue);
    <%_ if (enableTranslation) { _%>
    i18n = config.initI18N(localVue);
    <%_ } %>
  });

  it('should init service and do not retrieve account', async () => {
    mockedAxios.get.mockReturnValue(Promise.resolve({ data: { 'display-ribbon-on-profiles': 'dev', activeProfiles : ['dev', 'test']}}));
    <%_ if (authenticationType === 'session' || authenticationType === 'oauth2') { _%>const cookie = {get: jest.fn()};<%_ } %>
    accountService = await new AccountService(store, <%_ if (enableTranslation) { _%>new TranslationService(store, i18n),<%_ } %><%_ if (authenticationType === 'session' || authenticationType === 'oauth2') { _%>cookie,<%_ } %><%_ if (websocket === 'spring-websocket') { _%>null,<%_ } %> router);

    expect(store.getters.logon).toBe(false);
    expect(accountService.authenticated).toBe(false);
    expect(store.getters.account).toBe(null);
    expect(mockedAxios.get).toHaveBeenCalledWith('management/info');
    expect(store.getters.activeProfiles[0]).toBe('dev');
    expect(store.getters.activeProfiles[1]).toBe('test');
    expect(store.getters.ribbonOnProfiles).toBe('dev');
  });

  it('should init service and retrieve profiles if already logged in before but no account found', async () => {
    <%_ if (authenticationType == 'jwt') { _%>
    localStorage.setItem('<%=jhiPrefixDashed %>-authenticationToken', 'token');
    <%_ } %>
    mockedAxios.get.mockReturnValue(Promise.resolve({}));
    accountService = await new AccountService(store, <%_ if (enableTranslation) { _%>new TranslationService(store, i18n),<%_ } %><%_ if (authenticationType === 'session' || authenticationType === 'oauth2') { _%>mockedCookie,<%_ } %><%_ if (websocket === 'spring-websocket') { _%>null,<%_ } %> router);

    expect((<any>router).history.current.fullPath).toBe('/');
    expect(store.getters.logon).toBe(false);
    expect(accountService.authenticated).toBe(false);
    expect(store.getters.account).toBe(null);
    expect(mockedAxios.get).toHaveBeenCalledWith('management/info');
  });

  it('should init service and retrieve profiles if already logged in before but exception occurred and should be logged out', async () => {
    <%_ if (authenticationType == 'jwt') { _%>
    localStorage.setItem('<%=jhiPrefixDashed %>-authenticationToken', 'token');
    <%_ } %>
    mockedAxios.get = jest.fn(apiName => apiName === 'api/account' ? Promise.reject() : Promise.resolve({}));
    accountService = await new AccountService(store, <%_ if (enableTranslation) { _%>new TranslationService(store, i18n),<%_ } %><%_ if (authenticationType === 'session' || authenticationType === 'oauth2') { _%>mockedCookie,<%_ } %><%_ if (websocket === 'spring-websocket') { _%>null,<%_ } %> router);

    expect((<any>router).history.current.fullPath).toBe('/');
    expect(accountService.authenticated).toBe(false);
    expect(store.getters.account).toBe(null);
    expect(mockedAxios.get).toHaveBeenCalledWith('management/info');
  });

  it('should init service and check for authority after retrieving account but getAccount failed', async () => {
    <%_ if (websocket === 'spring-websocket') { _%>
    const trackerService = new TrackerService(null);
    trackerService.connect = jest.fn();
    <%_ } _%>
    <%_ if (authenticationType == 'jwt') { _%>
    localStorage.setItem('<%=jhiPrefixDashed %>-authenticationToken', 'token');
    <%_ } %>
    mockedAxios.get = jest.fn(apiName => Promise.reject());
    accountService = await new AccountService(store, <%_ if (enableTranslation) { _%>new TranslationService(store, i18n),<%_ } %><%_ if (authenticationType === 'session' || authenticationType === 'oauth2') { _%>mockedCookie,<%_ } %><%_ if (websocket === 'spring-websocket') { _%>trackerService,<%_ } %> router);

    return accountService.hasAnyAuthorityAndCheckAuth('USER').then((value: boolean) => {
      expect(value).toBe(false);
    });
  });

  it('should init service and check for authority after retrieving account', async () => {
    <%_ if (websocket === 'spring-websocket') { _%>
    const trackerService = new TrackerService(null);
    trackerService.connect = jest.fn();
    <%_ } _%>
    <%_ if (authenticationType == 'jwt') { _%>
    localStorage.setItem('<%=jhiPrefixDashed %>-authenticationToken', 'token');
    <%_ } %>
    mockedAxios.get.mockReturnValue(Promise.resolve({ data: { authorities: ['USER'] } }));
    accountService = await new AccountService(store, <%_ if (enableTranslation) { _%>new TranslationService(store, i18n),<%_ } %><%_ if (authenticationType === 'session' || authenticationType === 'oauth2') { _%>mockedCookie,<%_ } %><%_ if (websocket === 'spring-websocket') { _%>trackerService,<%_ } %> router);

    return accountService.hasAnyAuthorityAndCheckAuth('USER').then((value: boolean) => {
      expect(value).toBe(true);
    });
  });

  it('should init service as not authentified and not return any authorities admin and not retrieve account', async () => {
    mockedAxios.get = jest.fn(apiName => (apiName === 'api/account' ? Promise.reject() : Promise.resolve({})));
    accountService = await new AccountService(store, <%_ if (enableTranslation) { _%>new TranslationService(store, i18n),<%_ } %><%_ if (authenticationType === 'session' || authenticationType === 'oauth2') { _%>mockedCookie,<%_ } %><%_ if (websocket === 'spring-websocket') { _%>null,<%_ } %> router);

    return accountService.hasAnyAuthorityAndCheckAuth('ADMIN').then((value: boolean) => {
      expect(value).toBe(false);
    });
  });

  it('should init service as not authentified and return authority user', async () => {
    mockedAxios.get = jest.fn(apiName => (apiName === 'api/account' ? Promise.reject() : Promise.resolve({})));
    accountService = await new AccountService(store, <%_ if (enableTranslation) { _%>new TranslationService(store, i18n),<%_ } %><%_ if (authenticationType === 'session' || authenticationType === 'oauth2') { _%>mockedCookie,<%_ } %><%_ if (websocket === 'spring-websocket') { _%>null,<%_ } %> router);

    return accountService.hasAnyAuthorityAndCheckAuth('USER').then((value: boolean) => {
      expect(value).toBe(true);
    });
  });

});
